using System;
using System.Collections.Specialized;
using System.Data;
using System.Text;

namespace Chaotic.DataBase.DataAccess
{
	public class SqlGenerator
	{
		private static readonly SqlGenerator singleton = new SqlGenerator();

		private SqlGenerator()
		{
		}

		public static SqlGenerator Instance()
		{
			return singleton;
		}

		public SqlStruct GenerateSql(DataSet entity, SqlOperationType sqlOperationType)
		{
			if (entity.Tables.Count < 1)
			{
				throw new Exception("Table 0 does not exist!");
			}
			return GenerateSql(entity.Tables[0], sqlOperationType);
		}

		public SqlStruct GenerateSql(DataSet entity, int table, SqlOperationType sqlOperationType)
		{
			if (entity.Tables[table] == null)
			{
				throw new Exception("Table " + table + " does not exist!");
			}
			return GenerateSql(entity.Tables[table], sqlOperationType);
		}

		public SqlStruct GenerateSql(DataSet entity, string table, SqlOperationType sqlOperationType)
		{
			if (!entity.Tables.Contains(table))
			{
				throw new Exception("Table " + table + " does not exist!");
			}
			return GenerateSql(entity.Tables[table], sqlOperationType);
		}

		public SqlStruct GenerateSql(DataTable table, SqlOperationType sqlOperationType)
		{
			DataColumn[] primaryKey = table.PrimaryKey;
			string[] array = new string[primaryKey.Length];
			for (int i = 0; i < primaryKey.Length; i++)
			{
				array[i] = primaryKey[i].ColumnName;
			}
			return sqlOperationType switch
			{
				SqlOperationType.SimpleSelect => new SqlStruct(GenerateSimpleSelectSql(table), null),
				SqlOperationType.SelectByKey => GenerateFindByKeySql(table, array),
				SqlOperationType.Insert => GenerateInsertSql(table),
				SqlOperationType.Update => GenerateUpdateSql(table, array),
				SqlOperationType.Delete => GenerateDeleteSql(table, array),
				SqlOperationType.SelectByParent => GenerateFindByParentSql(table),
				SqlOperationType.DeleteByParent => GenerateDeleteByParentSql(table),
				_ => null,
			};
		}

		private string GenerateSimpleSelectSql(DataTable table)
		{
			string[] array = new string[table.Columns.Count];
			for (int i = 0; i < array.Length; i++)
			{
				array[i] = table.Columns[i].ColumnName;
			}
			return new StringBuilder("SELECT ").Append(string.Join(",", array)).Append(" FROM ").Append(table.TableName)
				.ToString();
		}

		private SqlStruct GenerateInsertSql(DataTable table)
		{
			string[] array = new string[table.Columns.Count];
			string[] array2 = new string[table.Columns.Count];
			ParamField[] array3 = new ParamField[table.Columns.Count];
			for (int i = 0; i < array.Length; i++)
			{
				array[i] = table.Columns[i].ColumnName;
				if (PersistenceProperty.DatabaseType == DatabaseType.MSSQLServer)
				{
					array2[i] = "@" + array[i];
				}
				else
				{
					array2[i] = ":" + array[i];
				}
				array3[i] = new ParamField(array2[i], array[i]);
			}
			return new SqlStruct(new StringBuilder("INSERT INTO ").Append(table.TableName).Append("(").Append(string.Join(",", array))
				.Append(") VALUES(")
				.Append(string.Join(",", array2))
				.Append(")")
				.ToString(), array3);
		}

		private SqlStruct GenerateUpdateSql(DataTable table, string[] keyColumns)
		{
			NameValueCollection nameValueCollection = new NameValueCollection();
			for (int i = 0; i < table.Columns.Count; i++)
			{
				nameValueCollection.Add(table.Columns[i].ColumnName, table.Columns[i].ColumnName);
			}
			foreach (string name in keyColumns)
			{
				nameValueCollection.Remove(name);
			}
			string[] array = new string[nameValueCollection.Count];
			ParamField[] array2 = new ParamField[nameValueCollection.Count + keyColumns.Length];
			for (int k = 0; k < nameValueCollection.Count; k++)
			{
				if (PersistenceProperty.DatabaseType == DatabaseType.MSSQLServer)
				{
					array[k] = new StringBuilder(nameValueCollection[k]).Append("=@").Append(nameValueCollection[k]).ToString();
					array2[k] = new ParamField("@" + nameValueCollection[k], nameValueCollection[k]);
				}
				else
				{
					array[k] = new StringBuilder(nameValueCollection[k]).Append("=:").Append(nameValueCollection[k]).ToString();
					array2[k] = new ParamField(":" + nameValueCollection[k], nameValueCollection[k]);
				}
			}
			string[] array3 = new string[keyColumns.Length];
			for (int l = 0; l < keyColumns.Length; l++)
			{
				if (PersistenceProperty.DatabaseType == DatabaseType.MSSQLServer)
				{
					array3[l] = new StringBuilder(keyColumns[l]).Append("=@").Append(keyColumns[l]).ToString();
					array2[nameValueCollection.Count + l] = new ParamField("@" + keyColumns[l], keyColumns[l]);
				}
				else
				{
					array3[l] = new StringBuilder(keyColumns[l]).Append("=:").Append(keyColumns[l]).ToString();
					array2[nameValueCollection.Count + l] = new ParamField(":" + keyColumns[l], keyColumns[l]);
				}
			}
			return new SqlStruct(new StringBuilder("UPDATE ").Append(table.TableName).Append(" SET ").Append(string.Join(",", array))
				.Append(" WHERE ")
				.Append(string.Join(" AND ", array3))
				.ToString(), array2);
		}

		private SqlStruct GenerateDeleteSql(DataTable table, string[] keyColumns)
		{
			string[] array = new string[keyColumns.Length];
			ParamField[] array2 = new ParamField[keyColumns.Length];
			for (int i = 0; i < keyColumns.Length; i++)
			{
				if (PersistenceProperty.DatabaseType == DatabaseType.MSSQLServer)
				{
					array[i] = new StringBuilder(keyColumns[i]).Append("=@").Append(keyColumns[i]).ToString();
					array2[i] = new ParamField("@" + keyColumns[i], keyColumns[i]);
				}
				else
				{
					array[i] = new StringBuilder(keyColumns[i]).Append("=:").Append(keyColumns[i]).ToString();
					array2[i] = new ParamField(":" + keyColumns[i], keyColumns[i]);
				}
			}
			return new SqlStruct(new StringBuilder("DELETE FROM ").Append(table.TableName).Append(" WHERE ").Append(string.Join(" AND ", array))
				.ToString(), array2);
		}

		private SqlStruct GenerateFindByKeySql(DataTable table, string[] keyColumns)
		{
			string[] array = new string[table.Columns.Count];
			for (int i = 0; i < array.Length; i++)
			{
				array[i] = table.Columns[i].ColumnName;
			}
			string[] array2 = new string[keyColumns.Length];
			ParamField[] array3 = new ParamField[keyColumns.Length];
			for (int j = 0; j < keyColumns.Length; j++)
			{
				if (PersistenceProperty.DatabaseType == DatabaseType.MSSQLServer)
				{
					array2[j] = new StringBuilder(keyColumns[j]).Append("=@").Append(keyColumns[j]).ToString();
					array3[j] = new ParamField("@" + keyColumns[j], keyColumns[j]);
				}
				else
				{
					array2[j] = new StringBuilder(keyColumns[j]).Append("=:").Append(keyColumns[j]).ToString();
					array3[j] = new ParamField(":" + keyColumns[j], keyColumns[j]);
				}
			}
			return new SqlStruct(new StringBuilder("SELECT ").Append(string.Join(",", array)).Append(" FROM ").Append(table.TableName)
				.Append(" WHERE ")
				.Append(string.Join(" AND ", array2))
				.ToString(), array3);
		}

		private SqlStruct GenerateFindByParentSql(DataTable table)
		{
			string[] array = new string[table.Columns.Count];
			for (int i = 0; i < array.Length; i++)
			{
				array[i] = table.Columns[i].ColumnName;
			}
			string tableName = table.DataSet.Tables[0].TableName;
			string text = "";
			DataRelationCollection relations = table.DataSet.Relations;
			for (int j = 0; j < relations.Count; j++)
			{
				if (relations[j].ParentTable.TableName.Equals(tableName) && relations[j].ChildTable.TableName.Equals(table.TableName))
				{
					text = relations[j].ChildColumns[0].ColumnName;
				}
			}
			string value;
			ParamField[] paramField;
			if (PersistenceProperty.DatabaseType == DatabaseType.MSSQLServer)
			{
				value = text + "=@" + text;
				paramField = new ParamField[1]
				{
				new ParamField("@" + text, text)
				};
			}
			else
			{
				value = text + "=:" + text;
				paramField = new ParamField[1]
				{
				new ParamField(":" + text, text)
				};
			}
			return new SqlStruct(new StringBuilder("SELECT ").Append(string.Join(",", array)).Append(" FROM ").Append(table.TableName)
				.Append(" WHERE ")
				.Append(value)
				.ToString(), paramField);
		}

		private SqlStruct GenerateDeleteByParentSql(DataTable table)
		{
			string tableName = table.DataSet.Tables[0].TableName;
			string text = "";
			DataRelationCollection relations = table.DataSet.Relations;
			for (int i = 0; i < relations.Count; i++)
			{
				if (relations[i].ParentTable.TableName.Equals(tableName) && relations[i].ChildTable.TableName.Equals(table.TableName))
				{
					text = relations[i].ChildColumns[0].ColumnName;
				}
			}
			string value;
			ParamField[] paramField;
			if (PersistenceProperty.DatabaseType == DatabaseType.MSSQLServer)
			{
				value = text + "=@" + text;
				paramField = new ParamField[1]
				{
				new ParamField("@" + text, text)
				};
			}
			else
			{
				value = text + "=:" + text;
				paramField = new ParamField[1]
				{
				new ParamField(":" + text, text)
				};
			}
			return new SqlStruct(new StringBuilder("DELETE FROM ").Append(table.TableName).Append(" WHERE ").Append(value)
				.ToString(), paramField);
		}
	}
}